/*
MIT License

Copyright (c) 2022 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов,

https://bmstu.codes/lsx/simodo/loom
*/

#ifndef simodo_module_variable_Stack
#define simodo_module_variable_Stack

/*! \file VariableStack.h
    \brief Реализация стека переменных машины SBL
*/

#include "simodo/variable/Variable.h"

namespace simodo::variable
{
    inline const size_t DEFAULT_VARIABLE_STACK_SIZE = 1000;

    class VariableStack
    {
        VariableSet_t _stack;

    public:
        VariableStack(size_t stack_size = DEFAULT_VARIABLE_STACK_SIZE);

    public:
        size_t                  size()  const { return _stack.size(); }
        VariableSet_t &         stack()       { return _stack; }
        const VariableSet_t &   stack() const { return _stack; }

        /// \todo temporary
        size_t              capacity() const { return _stack.capacity(); }

    public:
        void                push(Variable v);
        Variable            pop();
        void                popAmount(size_t n);
        const Variable &    top(size_t shift_from_top=0) const ;
        Variable &          top(size_t shift_from_top=0);
        const Variable &    at(size_t index) const ;
        Variable &          at(size_t index);

        const Variable &    back() const { return top(); }
        Variable &          back() { return top(); }

        std::shared_ptr<variable::Object> convertToObject(size_t stack_start_position);
    };
}

#endif // simodo_module_variable_Stack
